Просмотр исходного кода

Merge branch 'nightscout:dev' into removePlaySoundIfNeededFeature

kskandis 1 год назад
Родитель
Сommit
b48b4092cb

+ 71 - 4
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -1224,6 +1224,9 @@
         }
         }
       }
       }
     },
     },
+    " %@/U" : {
+
+    },
     " + " : {
     " + " : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -2203,6 +2206,9 @@
         }
         }
       }
       }
     },
     },
+    " needed as min. Glucose Target)!" : {
+
+    },
     " of " : {
     " of " : {
       "comment" : "Bolus string partial message: 'x U of y U' in home view"
       "comment" : "Bolus string partial message: 'x U of y U' in home view"
     },
     },
@@ -5365,6 +5371,7 @@
       }
       }
     },
     },
     "%" : {
     "%" : {
+      "comment" : "Percentage symbol",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -6131,6 +6138,7 @@
       }
       }
     },
     },
     "%@ g/U" : {
     "%@ g/U" : {
+      "extractionState" : "stale",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -26201,6 +26209,9 @@
         }
         }
       }
       }
     },
     },
+    "All settings are at default values." : {
+
+    },
     "Allow Bolusing with Shortcuts" : {
     "Allow Bolusing with Shortcuts" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -28001,6 +28012,9 @@
     "Alter the rate of dynamic sensitivity adjustments for Sigmoid." : {
     "Alter the rate of dynamic sensitivity adjustments for Sigmoid." : {
 
 
     },
     },
+    "Always" : {
+      "extractionState" : "manual"
+    },
     "Always Color Glucose Value (green, yellow etc)" : {
     "Always Color Glucose Value (green, yellow etc)" : {
       "comment" : "UI/UX option",
       "comment" : "UI/UX option",
       "extractionState" : "manual",
       "extractionState" : "manual",
@@ -47808,6 +47822,7 @@
       }
       }
     },
     },
     "CR" : {
     "CR" : {
+      "comment" : "Option for Carb Ratio",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -49460,6 +49475,9 @@
         }
         }
       }
       }
     },
     },
+    "Dark" : {
+
+    },
     "Dark Mode" : {
     "Dark Mode" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -59235,6 +59253,12 @@
         }
         }
       }
       }
     },
     },
+    "Disable" : {
+      "extractionState" : "manual"
+    },
+    "Disable on Schedule" : {
+      "extractionState" : "manual"
+    },
     "Disable SMBs" : {
     "Disable SMBs" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -62853,6 +62877,9 @@
         }
         }
       }
       }
     },
     },
+    "Don't Disable" : {
+      "extractionState" : "manual"
+    },
     "Done" : {
     "Done" : {
       "comment" : "Button",
       "comment" : "Button",
       "extractionState" : "manual",
       "extractionState" : "manual",
@@ -63499,6 +63526,9 @@
         }
         }
       }
       }
     },
     },
+    "Dynamic" : {
+
+    },
     "Dynamic CR adjusts your carb ratio based on your Dynamic Ratio, adapting automatically to changes in insulin sensitivity." : {
     "Dynamic CR adjusts your carb ratio based on your Dynamic Ratio, adapting automatically to changes in insulin sensitivity." : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -66247,6 +66277,9 @@
         }
         }
       }
       }
     },
     },
+    "Enable indefinitely or set a duration." : {
+
+    },
     "Enable Live Activity" : {
     "Enable Live Activity" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -79477,7 +79510,7 @@
       }
       }
     },
     },
     "g" : {
     "g" : {
-      "comment" : "The short unit display string for grams\ngram of carbs",
+      "comment" : "Gram abbreviation\nThe short unit display string for grams\ngram of carbs",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -87527,6 +87560,9 @@
     "How Trio Manages Contact Images" : {
     "How Trio Manages Contact Images" : {
 
 
     },
     },
+    "hr" : {
+      "comment" : "Hours abbreviation"
+    },
     "If \"Display IOB and COB\" is also enabled, \"IOB\" and \"COB\" will be replaced with the following emojis:" : {
     "If \"Display IOB and COB\" is also enabled, \"IOB\" and \"COB\" will be replaced with the following emojis:" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -94400,6 +94436,7 @@
 
 
     },
     },
     "ISF" : {
     "ISF" : {
+      "comment" : "Option for Insulin Sensitivity Factor",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -94611,6 +94648,9 @@
         }
         }
       }
       }
     },
     },
+    "ISF/CR" : {
+      "comment" : "Option for both ISF and CR"
+    },
     "It allows you to refer to live information at a glance and perform quick actions in your diabetes management." : {
     "It allows you to refer to live information at a glance and perform quick actions in your diabetes management." : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -97014,6 +97054,9 @@
         }
         }
       }
       }
     },
     },
+    "Light" : {
+
+    },
     "Light Mode" : {
     "Light Mode" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -98318,6 +98361,9 @@
     "Live Activity Expired. Open Trio to Refresh" : {
     "Live Activity Expired. Open Trio to Refresh" : {
 
 
     },
     },
+    "Live Activity Personalization" : {
+
+    },
     "Local glucose source" : {
     "Local glucose source" : {
       "extractionState" : "manual",
       "extractionState" : "manual",
       "localizations" : {
       "localizations" : {
@@ -107156,7 +107202,7 @@
       }
       }
     },
     },
     "min" : {
     "min" : {
-      "comment" : "Minutes ago since last loop\nShort form for minutes",
+      "comment" : "Minutes abbreviation\nMinutes ago since last loop\nShort form for minutes",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -113178,7 +113224,7 @@
 
 
     },
     },
     "None" : {
     "None" : {
-      "comment" : "No CGM selected",
+      "comment" : "No CGM selected\nOption for no selection",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {
@@ -115987,6 +116033,9 @@
         }
         }
       }
       }
     },
     },
+    "Note..." : {
+
+    },
     "Notes" : {
     "Notes" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -118264,6 +118313,9 @@
         }
         }
       }
       }
     },
     },
+    "Only Alarm Limits" : {
+      "extractionState" : "manual"
+    },
     "Only Alarm Limits:" : {
     "Only Alarm Limits:" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -124019,6 +124071,9 @@
         }
         }
       }
       }
     },
     },
+    "Presets cannot be saved with a future date!" : {
+
+    },
     "Preview Contact Image" : {
     "Preview Contact Image" : {
 
 
     },
     },
@@ -136610,6 +136665,9 @@
     "Set a custom time for peak insulin effect." : {
     "Set a custom time for peak insulin effect." : {
       "comment" : "Mini Hint for Insulin Peak Time"
       "comment" : "Mini Hint for Insulin Peak Time"
     },
     },
+    "Set a duration!" : {
+
+    },
     "Set Display Values" : {
     "Set Display Values" : {
 
 
     },
     },
@@ -145289,6 +145347,9 @@
         }
         }
       }
       }
     },
     },
+    "Static" : {
+
+    },
     "Static:" : {
     "Static:" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -148648,6 +148709,9 @@
         }
         }
       }
       }
     },
     },
+    "System Default" : {
+
+    },
     "System Default:" : {
     "System Default:" : {
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
@@ -149513,6 +149577,9 @@
         }
         }
       }
       }
     },
     },
+    "Target glucose is out of range (%@)." : {
+
+    },
     "Target presets" : {
     "Target presets" : {
       "comment" : "Debug option view Target presets",
       "comment" : "Debug option view Target presets",
       "extractionState" : "manual",
       "extractionState" : "manual",
@@ -169478,7 +169545,7 @@
       }
       }
     },
     },
     "U" : {
     "U" : {
-      "comment" : "Insulin unit\nThe short unit display string for international units of insulin",
+      "comment" : "Insulin unit\nInsulin unit abbreviation\nThe short unit display string for international units of insulin",
       "localizations" : {
       "localizations" : {
         "ar" : {
         "ar" : {
           "stringUnit" : {
           "stringUnit" : {

+ 3 - 3
Trio/Sources/Models/ColorSchemeOption.swift

@@ -7,9 +7,9 @@ enum ColorSchemeOption: String, JSON, CaseIterable, Identifiable {
 
 
     var displayName: String {
     var displayName: String {
         switch self {
         switch self {
-        case .systemDefault: return "System Default"
-        case .light: return "Light"
-        case .dark: return "Dark"
+        case .systemDefault: return String(localized: "System Default")
+        case .light: return String(localized: "Light")
+        case .dark: return String(localized: "Dark")
         }
         }
     }
     }
 }
 }

+ 2 - 2
Trio/Sources/Models/GlucoseColorScheme.swift

@@ -10,9 +10,9 @@ public enum GlucoseColorScheme: String, JSON, CaseIterable, Identifiable, Codabl
     var displayName: String {
     var displayName: String {
         switch self {
         switch self {
         case .staticColor:
         case .staticColor:
-            return "Static"
+            return String(localized: "Static")
         case .dynamicColor:
         case .dynamicColor:
-            return "Dynamic"
+            return String(localized: "Dynamic")
         }
         }
     }
     }
 }
 }

+ 9 - 4
Trio/Sources/Models/GlucoseNotificationsOption.swift

@@ -5,18 +5,23 @@
 //  Created by Kimberlie Skandis on 1/18/25.
 //  Created by Kimberlie Skandis on 1/18/25.
 //
 //
 import Foundation
 import Foundation
+import SwiftUI
 
 
 public enum GlucoseNotificationsOption: String, JSON, CaseIterable, Identifiable, Codable, Hashable {
 public enum GlucoseNotificationsOption: String, JSON, CaseIterable, Identifiable, Codable, Hashable {
-    public var id: String { rawValue }
     case disabled
     case disabled
     case alwaysEveryCGM
     case alwaysEveryCGM
     case onlyAlarmLimits
     case onlyAlarmLimits
 
 
+    public var id: String { rawValue }
+
     var displayName: String {
     var displayName: String {
         switch self {
         switch self {
-        case .disabled: return "Disabled"
-        case .alwaysEveryCGM: return "Always"
-        case .onlyAlarmLimits: return "Only Alarm Limits"
+        case .disabled:
+            return String(localized: "Disabled", comment: "Option to disable glucose notifications")
+        case .alwaysEveryCGM:
+            return String(localized: "Always", comment: "Option to always notify on every CGM reading")
+        case .onlyAlarmLimits:
+            return String(localized: "Only Alarm Limits", comment: "Option to notify only when glucose reaches alarm limits")
         }
         }
     }
     }
 }
 }

+ 32 - 7
Trio/Sources/Modules/Adjustments/AdjustmentsStateModel+Extensions/AdjustmentsStateModel+Overrides.swift

@@ -1,6 +1,7 @@
 import Combine
 import Combine
 import CoreData
 import CoreData
 import Foundation
 import Foundation
+import SwiftUICore
 
 
 extension Adjustments.StateModel {
 extension Adjustments.StateModel {
     // MARK: - Enact Overrides
     // MARK: - Enact Overrides
@@ -370,14 +371,38 @@ extension Adjustments.StateModel {
 }
 }
 
 
 enum IsfAndOrCrOptions: String, CaseIterable {
 enum IsfAndOrCrOptions: String, CaseIterable {
-    case isfAndCr = "ISF/CR"
-    case isf = "ISF"
-    case cr = "CR"
-    case nothing = "None"
+    case isfAndCr
+    case isf
+    case cr
+    case nothing
+
+    var displayName: String {
+        switch self {
+        case .isfAndCr:
+            return String(localized: "ISF/CR", comment: "Option for both ISF and CR")
+        case .isf:
+            return String(localized: "ISF", comment: "Option for Insulin Sensitivity Factor")
+        case .cr:
+            return String(localized: "CR", comment: "Option for Carb Ratio")
+        case .nothing:
+            return String(localized: "None", comment: "Option for no selection")
+        }
+    }
 }
 }
 
 
 enum DisableSmbOptions: String, CaseIterable {
 enum DisableSmbOptions: String, CaseIterable {
-    case dontDisable = "Don't Disable"
-    case disable = "Disable"
-    case disableOnSchedule = "Disable on Schedule"
+    case dontDisable
+    case disable
+    case disableOnSchedule
+
+    var displayName: String {
+        switch self {
+        case .dontDisable:
+            return String(localized: "Don't Disable", comment: "Option to keep SMB enabled")
+        case .disable:
+            return String(localized: "Disable", comment: "Option to disable SMB")
+        case .disableOnSchedule:
+            return String(localized: "Disable on Schedule", comment: "Option to disable SMB based on schedule")
+        }
+    }
 }
 }

+ 5 - 5
Trio/Sources/Modules/Adjustments/View/Overrides/AddOverrideForm.swift

@@ -124,7 +124,7 @@ struct AddOverrideForm: View {
                 // Picker for ISF/CR settings
                 // Picker for ISF/CR settings
                 Picker("Also Inversely Change", selection: $selectedIsfCrOption) {
                 Picker("Also Inversely Change", selection: $selectedIsfCrOption) {
                     ForEach(IsfAndOrCrOptions.allCases, id: \.self) { option in
                     ForEach(IsfAndOrCrOptions.allCases, id: \.self) { option in
-                        Text(option.rawValue).tag(option)
+                        Text(option.displayName).tag(option)
                     }
                     }
                 }
                 }
                 .pickerStyle(MenuPickerStyle())
                 .pickerStyle(MenuPickerStyle())
@@ -188,7 +188,7 @@ struct AddOverrideForm: View {
                 // Picker for ISF/CR settings
                 // Picker for ISF/CR settings
                 Picker("Disable SMBs", selection: $selectedDisableSmbOption) {
                 Picker("Disable SMBs", selection: $selectedDisableSmbOption) {
                     ForEach(DisableSmbOptions.allCases, id: \.self) { option in
                     ForEach(DisableSmbOptions.allCases, id: \.self) { option in
-                        Text(option.rawValue).tag(option)
+                        Text(option.displayName).tag(option)
                     }
                     }
                 }
                 }
                 .pickerStyle(MenuPickerStyle())
                 .pickerStyle(MenuPickerStyle())
@@ -448,15 +448,15 @@ struct AddOverrideForm: View {
             !state.advancedSettings && !state.smbIsOff && !state.smbIsScheduledOff
             !state.advancedSettings && !state.smbIsOff && !state.smbIsScheduledOff
 
 
         if noDurationSpecified {
         if noDurationSpecified {
-            return (true, "Enable indefinitely or set a duration.")
+            return (true, String(localized: "Enable indefinitely or set a duration."))
         }
         }
 
 
         if targetZeroWithOverride {
         if targetZeroWithOverride {
-            return (true, "Target glucose is out of range (\(state.units == .mgdL ? "72-270" : "4-14")).")
+            return (true, String(localized: "Target glucose is out of range (\(state.units == .mgdL ? "72-270" : "4-14"))."))
         }
         }
 
 
         if allSettingsDefault {
         if allSettingsDefault {
-            return (true, "All settings are at default values.")
+            return (true, String(localized: "All settings are at default values."))
         }
         }
 
 
         return (false, nil)
         return (false, nil)

+ 5 - 5
Trio/Sources/Modules/Adjustments/View/Overrides/EditOverrideForm.swift

@@ -187,7 +187,7 @@ struct EditOverrideForm: View {
                 // Picker for ISF/CR settings
                 // Picker for ISF/CR settings
                 Picker("Also Change", selection: $selectedIsfCrOption) {
                 Picker("Also Change", selection: $selectedIsfCrOption) {
                     ForEach(IsfAndOrCrOptions.allCases, id: \.self) { option in
                     ForEach(IsfAndOrCrOptions.allCases, id: \.self) { option in
-                        Text(option.rawValue).tag(option)
+                        Text(option.displayName).tag(option)
                     }
                     }
                 }
                 }
                 .pickerStyle(MenuPickerStyle())
                 .pickerStyle(MenuPickerStyle())
@@ -257,7 +257,7 @@ struct EditOverrideForm: View {
                 // Picker for Disable SMB settings
                 // Picker for Disable SMB settings
                 Picker("Disable SMBs", selection: $selectedDisableSmbOption) {
                 Picker("Disable SMBs", selection: $selectedDisableSmbOption) {
                     ForEach(DisableSmbOptions.allCases, id: \.self) { option in
                     ForEach(DisableSmbOptions.allCases, id: \.self) { option in
-                        Text(option.rawValue).tag(option)
+                        Text(option.displayName).tag(option)
                     }
                     }
                 }
                 }
                 .pickerStyle(MenuPickerStyle())
                 .pickerStyle(MenuPickerStyle())
@@ -557,15 +557,15 @@ struct EditOverrideForm: View {
             !smbIsOff && !smbIsScheduledOff
             !smbIsOff && !smbIsScheduledOff
 
 
         if noDurationSpecified {
         if noDurationSpecified {
-            return (true, "Enable indefinitely or set a duration.")
+            return (true, String(localized: "Enable indefinitely or set a duration."))
         }
         }
 
 
         if targetZeroWithOverride {
         if targetZeroWithOverride {
-            return (true, "Target glucose is out of range (\(state.units == .mgdL ? "72-270" : "4-14")).")
+            return (true, String(localized: "Target glucose is out of range (\(state.units == .mgdL ? "72-270" : "4-14"))."))
         }
         }
 
 
         if allSettingsDefault {
         if allSettingsDefault {
-            return (true, "All settings are at default values.")
+            return (true, String(localized: "All settings are at default values."))
         }
         }
 
 
         if !hasChanges {
         if !hasChanges {

+ 5 - 4
Trio/Sources/Modules/Adjustments/View/TempTargets/AddTempTargetForm.swift

@@ -84,7 +84,7 @@ struct AddTempTargetForm: View {
                 let settingsProvider = PickerSettingsProvider.shared
                 let settingsProvider = PickerSettingsProvider.shared
                 let glucoseSetting = PickerSetting(value: 0, step: targetStep, min: 80, max: 200, type: .glucose)
                 let glucoseSetting = PickerSetting(value: 0, step: targetStep, min: 80, max: 200, type: .glucose)
                 TargetPicker(
                 TargetPicker(
-                    label: "Target Glucose",
+                    label: String(localized: "Target Glucose"),
                     selection: Binding(
                     selection: Binding(
                         get: { state.tempTargetTarget },
                         get: { state.tempTargetTarget },
                         set: { state.tempTargetTarget = $0 }
                         set: { state.tempTargetTarget = $0 }
@@ -205,13 +205,14 @@ struct AddTempTargetForm: View {
         let targetZero = state.tempTargetTarget < 80
         let targetZero = state.tempTargetTarget < 80
 
 
         if noDurationSpecified {
         if noDurationSpecified {
-            return (true, "Set a duration!")
+            return (true, String(localized: "Set a duration!"))
         }
         }
 
 
         if targetZero {
         if targetZero {
             return (
             return (
                 true,
                 true,
-                "\(state.units == .mgdL ? "80 " : "4.4 ")" + state.units.rawValue + " needed as min. Glucose Target!"
+                "\(state.units == .mgdL ? "80 " : "4.4 ")" + state.units
+                    .rawValue + String(localized: " needed as min. Glucose Target)!")
             )
             )
         }
         }
 
 
@@ -227,7 +228,7 @@ struct AddTempTargetForm: View {
         }
         }
 
 
         if isDateInFuture {
         if isDateInFuture {
-            return (true, "Presets can't be saved with a future date!")
+            return (true, String(localized: "Presets cannot be saved with a future date!"))
         }
         }
 
 
         return (false, nil)
         return (false, nil)

+ 2 - 4
Trio/Sources/Modules/BasalProfileEditor/View/BasalProfileEditorRootView.swift

@@ -195,10 +195,8 @@ extension BasalProfileEditor {
                     Picker(selection: $state.items[index].rateIndex, label: Text("Rate")) {
                     Picker(selection: $state.items[index].rateIndex, label: Text("Rate")) {
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                             Text(
                             Text(
-                                (
-                                    self.rateFormatter
-                                        .string(from: state.rateValues[i] as NSNumber) ?? ""
-                                ) + " U/hr"
+                                (self.rateFormatter.string(from: state.rateValues[i] as NSNumber) ?? "") + " " +
+                                    String(localized: "U/hr")
                             ).tag(i)
                             ).tag(i)
                         }
                         }
                     }
                     }

+ 4 - 5
Trio/Sources/Modules/CarbRatioEditor/View/CarbRatioEditorRootView.swift

@@ -125,10 +125,8 @@ extension CarbRatioEditor {
                     Picker(selection: $state.items[index].rateIndex, label: Text("Ratio")) {
                     Picker(selection: $state.items[index].rateIndex, label: Text("Ratio")) {
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                             Text(
                             Text(
-                                (
-                                    self.rateFormatter
-                                        .string(from: state.rateValues[i] as NSNumber) ?? ""
-                                ) + " g/U"
+                                (self.rateFormatter.string(from: state.rateValues[i] as NSNumber) ?? "") + " " +
+                                    String(localized: "g/U")
                             ).tag(i)
                             ).tag(i)
                         }
                         }
                     }
                     }
@@ -163,7 +161,8 @@ extension CarbRatioEditor {
                         HStack {
                         HStack {
                             Text("Ratio").foregroundColor(.secondary)
                             Text("Ratio").foregroundColor(.secondary)
                             Text(
                             Text(
-                                "\(rateFormatter.string(from: state.rateValues[item.rateIndex] as NSNumber) ?? "0") g/U"
+                                (rateFormatter.string(from: state.rateValues[item.rateIndex] as NSNumber) ?? "0") + " " +
+                                    String(localized: "g/U")
                             )
                             )
                             Spacer()
                             Spacer()
                             Text("starts at").foregroundColor(.secondary)
                             Text("starts at").foregroundColor(.secondary)

+ 1 - 1
Trio/Sources/Modules/DataTable/View/CarbEntryEditorView.swift

@@ -161,7 +161,7 @@ struct CarbEntryEditorView: View {
 
 
                     HStack {
                     HStack {
                         Image(systemName: "square.and.pencil")
                         Image(systemName: "square.and.pencil")
-                        TextFieldWithToolBarString(text: $editedNote, placeholder: "Note...", maxLength: 25)
+                        TextFieldWithToolBarString(text: $editedNote, placeholder: String(localized: "Note..."), maxLength: 25)
                     }
                     }
                 }.listRowBackground(Color.chart)
                 }.listRowBackground(Color.chart)
 
 

+ 2 - 2
Trio/Sources/Modules/ISFEditor/View/ISFEditorRootView.swift

@@ -124,7 +124,7 @@ extension ISFEditor {
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                         ForEach(0 ..< state.rateValues.count, id: \.self) { i in
                             Text(
                             Text(
                                 state.units == .mgdL ? state.rateValues[i].description : state.rateValues[i]
                                 state.units == .mgdL ? state.rateValues[i].description : state.rateValues[i]
-                                    .formattedAsMmolL + " \(state.units.rawValue)/U"
+                                    .formattedAsMmolL + String(localized: " \(state.units.rawValue)/U")
                             ).tag(i)
                             ).tag(i)
                         }
                         }
                     }
                     }
@@ -162,7 +162,7 @@ extension ISFEditor {
                             Text("Rate").foregroundColor(.secondary)
                             Text("Rate").foregroundColor(.secondary)
 
 
                             Text(
                             Text(
-                                displayValue + " \(state.units.rawValue)/U"
+                                displayValue + String(localized: " \(state.units.rawValue)/U")
                             )
                             )
                             Spacer()
                             Spacer()
                             Text("starts at").foregroundColor(.secondary)
                             Text("starts at").foregroundColor(.secondary)

+ 1 - 1
Trio/Sources/Modules/LiveActivitySettings/View/LiveActivityWidgetConfiguration.swift

@@ -78,7 +78,7 @@ struct LiveActivityWidgetConfiguration: BaseView {
         VStack {
         VStack {
             Group {
             Group {
                 VStack(alignment: .trailing, spacing: 0) {
                 VStack(alignment: .trailing, spacing: 0) {
-                    Text("Live Activity Personalization".uppercased())
+                    Text(String(localized: "Live Activity Personalization").uppercased())
                         .frame(maxWidth: .infinity, alignment: .leading)
                         .frame(maxWidth: .infinity, alignment: .leading)
                         .foregroundColor(.secondary)
                         .foregroundColor(.secondary)
                         .font(.footnote)
                         .font(.footnote)

+ 6 - 2
Trio/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -228,7 +228,11 @@ extension Treatments {
                             // Notes
                             // Notes
                             HStack {
                             HStack {
                                 Image(systemName: "square.and.pencil")
                                 Image(systemName: "square.and.pencil")
-                                TextFieldWithToolBarString(text: $state.note, placeholder: "Note...", maxLength: 25)
+                                TextFieldWithToolBarString(
+                                    text: $state.note,
+                                    placeholder: String(localized: "Note..."),
+                                    maxLength: 25
+                                )
                             }
                             }
                         }.listRowBackground(Color.chart)
                         }.listRowBackground(Color.chart)
 
 
@@ -457,7 +461,7 @@ extension Treatments {
             let hasInsulin = state.amount > 0
             let hasInsulin = state.amount > 0
             let hasCarbs = state.carbs > 0
             let hasCarbs = state.carbs > 0
             let hasFatOrProtein = state.fat > 0 || state.protein > 0
             let hasFatOrProtein = state.fat > 0 || state.protein > 0
-            let bolusString = state.externalInsulin ? "External Insulin" : "Enact Bolus"
+            let bolusString = state.externalInsulin ? String(localized: "External Insulin") : String(localized: "Enact Bolus")
 
 
             if state.isBolusInProgress && hasInsulin && !state.externalInsulin && (!hasCarbs || !hasFatOrProtein) {
             if state.isBolusInProgress && hasInsulin && !state.externalInsulin && (!hasCarbs || !hasFatOrProtein) {
                 return Text("Bolus In Progress...")
                 return Text("Bolus In Progress...")

+ 5 - 5
Trio/Sources/Views/SettingInputSection.swift

@@ -215,15 +215,15 @@ struct SettingInputSection<VerboseHint: View>: View {
             let displayValue = units == .mmolL ? decimalValue.asMmolL : decimalValue
             let displayValue = units == .mmolL ? decimalValue.asMmolL : decimalValue
             return Text("\(displayValue.description) \(units.rawValue)")
             return Text("\(displayValue.description) \(units.rawValue)")
         case .factor:
         case .factor:
-            return Text("\(decimalValue * 100) %")
+            return Text("\(decimalValue * 100) \(String(localized: "%", comment: "Percentage symbol"))")
         case .insulinUnit:
         case .insulinUnit:
-            return Text("\(decimalValue) U")
+            return Text("\(decimalValue) \(String(localized: "U", comment: "Insulin unit abbreviation"))")
         case .gram:
         case .gram:
-            return Text("\(decimalValue) g")
+            return Text("\(decimalValue) \(String(localized: "g", comment: "Gram abbreviation"))")
         case .minute:
         case .minute:
-            return Text("\(decimalValue) min")
+            return Text("\(decimalValue) \(String(localized: "min", comment: "Minutes abbreviation"))")
         case .hour:
         case .hour:
-            return Text("\(decimalValue) hr")
+            return Text("\(decimalValue) \(String(localized: "hr", comment: "Hours abbreviation"))")
         }
         }
     }
     }